import { SessionGuard } from '@/guard/session.guard';
import {
  Body,
  Controller,
  Delete,
  Get,
  HttpException,
  HttpStatus,
  Param,
  Post,
  Put,
  Query,
  Req,
  Session,
  UseGuards,
} from '@nestjs/common';
import { UserService } from '../user/user.service';
import { BrandService } from './brand.service';
import { Request as HttpRequest } from 'express';
import { SessionType } from '@/types';
import {
  CreateBrandRequest,
  GetBrandsRequest,
  UpdateBrandRequest,
} from './dto/request.dto';
import { ResponseBody, ResponseCode } from '@/utils/ResponseCode';
import { Brand as BrandEntity } from '@/entity/Brand';

@UseGuards(SessionGuard)
@Controller('brand')
export class BrandController {
  constructor(
    private readonly brandService: BrandService,
    private readonly userService: UserService,
  ) {}

  @Get()
  async getBrands(
    @Query() query: GetBrandsRequest,
    @Req() request: HttpRequest,
    @Session() session: SessionType,
  ) {
    // 接口鉴权
    await this.userService.verifyPermission(request, session.username);
    const { current, pageSize, ...findWhere } = query;
    const { total, list } = await this.brandService.findAllAndCount(findWhere, {
      current,
      pageSize,
    });
    return new ResponseBody<{
      total: number;
      list: BrandEntity[];
    }>({
      data: { total, list },
      message: '获取品牌列表成功',
    });
  }

  // 创建品牌 start
  @Post()
  async createBrand(
    @Body() requestBody: CreateBrandRequest,
    @Req() request: HttpRequest,
    @Session() session: SessionType,
  ) {
    // 接口鉴权
    await this.userService.verifyPermission(request, session.username);
    const { name, marketPrice, coverUrl } = requestBody;
    const existBrand = await this.brandService.findOneBy({ name });
    if (existBrand) {
      return new ResponseBody({
        code: ResponseCode.Fail,
        message: '品牌名称已经存在',
      });
    }
    try {
      const brandEntity = await this.brandService.create({
        name,
        marketPrice,
        coverUrl,
        // 初始化库存为0
        stock: 0,
      });
      // 返回创建的品牌id
      return new ResponseBody<number>({
        message: '创建品牌成功',
        data: brandEntity.id,
      });
    } catch (error) {
      // 事务抛出错误的兜底
      throw new HttpException(
        {
          message: error,
          code: ResponseCode.Fail,
          data: null,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
  // 创建品牌 end

  // 更新品牌 start
  @Put(':id')
  async updateBrand(
    @Param('id') brandId: number,
    @Body() requestBody: UpdateBrandRequest,
    @Req() request: HttpRequest,
    @Session() session: SessionType,
  ) {
    // 接口鉴权
    await this.userService.verifyPermission(request, session.username);
    const { name, coverUrl, marketPrice } = requestBody;
    const oldBrandEntity = await this.brandService.findOneBy({
      name,
    });
    if (oldBrandEntity && oldBrandEntity.id !== Number(brandId)) {
      return new ResponseBody({
        code: ResponseCode.Fail,
        message: '品牌名称重复',
        data: oldBrandEntity,
      });
    }
    try {
      await this.brandService.update(
        {
          id: brandId,
        },
        {
          coverUrl,
          marketPrice,
          name,
        },
      );
      return new ResponseBody('更新品牌信息成功');
    } catch (error) {
      console.log(error);
      // 事务抛出错误的兜底
      throw new HttpException(
        {
          message: error,
          code: ResponseCode.Fail,
          data: null,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
  // 更新品牌 end

  @Delete(':id')
  async deleteBrand(
    @Param('id') brandId: number,
    @Req() request: HttpRequest,
    @Session() session: SessionType,
  ) {
    // 接口鉴权
    await this.userService.verifyPermission(request, session.username);
    try {
      await this.brandService.deleteBrandById(brandId);
      return new ResponseBody('删除品牌成功');
    } catch (error) {
      // 事务抛出错误的兜底
      throw new HttpException(
        {
          message: error,
          code: ResponseCode.Fail,
          data: null,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
}
